package com.jason.kotlinstudy;

import android.Manifest;
import android.content.ComponentCallbacks2;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.jason.kotlinstudy.annotation.DebugTrace;
import com.jason.kotlinstudy.annotation.Permission;
import com.jason.kotlinstudy.annotation.PermissionCancel;
import com.jason.kotlinstudy.annotation.PermissionDenied;
import com.jason.kotlinstudy.bean.BitmapBinder;

public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
    Handler mainHandler, workHandler;
    HandlerThread mHandlerThread;
    TextView text;
    Button button1, button2, button3;
    private String TAG = MainActivity.class.getSimpleName();

    static {
        System.loadLibrary("native-lib");
    }

    private native void nativeInit();

    @DebugTrace
    private void testAnnotatedMethod() {
        SystemClock.sleep(100);
    }

    @DebugTrace
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 显示文本
        text = (TextView) findViewById(R.id.text1);

        handlerThread();

        /**
         * 步骤4：使用工作线程Handler向工作线程的消息队列发送消息
         * 在工作线程中，当消息循环时取出对应消息 & 在工作线程执行相关操作
         */
        // 点击Button1
        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 通过sendMessage（）发送
                // a. 定义要发送的消息
                Message msg = Message.obtain();
                msg.what = 1; //消息的标识
                msg.obj = "A"; // 消息的存放
                // b. 通过Handler发送消息到其绑定的消息队列
                workHandler.sendMessage(msg);
            }
        });

        // 点击Button2
        button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 通过sendMessage（）发送
                // a. 定义要发送的消息
                Message msg = Message.obtain();
                msg.what = 2; //消息的标识
                msg.obj = "B"; // 消息的存放
                // b. 通过Handler发送消息到其绑定的消息队列
                workHandler.sendMessage(msg);
            }
        });

        // 点击Button3
        // 作用：退出消息循环
        button3 = (Button) findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mHandlerThread.quit();
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    reportFullyDrawn();
                    Log.i(TAG, "启动完毕了");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();

    }

    private void handlerThread() {
        // 创建与主线程关联的Handler
        mainHandler = new Handler();

        /**
         * 步骤1：创建HandlerThread实例对象
         * 传入参数 = 线程名字，作用 = 标记该线程
         */
        mHandlerThread = new HandlerThread("handlerThread");

        /**
         * 步骤2：启动线程
         */
        mHandlerThread.start();

        /**
         * 步骤3：创建工作线程Handler & 复写handleMessage（）
         * 作用：关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
         * 注：消息处理操作（HandlerMessage（））的执行线程 = mHandlerThread所创建的工作线程中执行
         */

        workHandler = new Handler(mHandlerThread.getLooper()) {
            @Override
            // 消息处理的操作
            public void handleMessage(Message msg) {
                //设置了两种消息处理操作,通过msg来进行识别
                switch (msg.what) {
                    // 消息1
                    case 1:
                        try {
                            //延时操作
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 通过主线程Handler.post方法进行在主线程的UI更新操作
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                text.setText("我爱学习");
                            }
                        });
                        break;

                    // 消息2
                    case 2:
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                text.setText("我不喜欢学习");
                            }
                        });
                        break;
                    default:
                        break;
                }
            }
        };
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
    }

    //供JNI端回调的Java方法
    public void onNativeCallBack(int count) {
        Log.e(TAG, "onNativeCallBack : " + count);
    }

    public void jniCall(View view) {
        nativeInit();
        Log.i(TAG, "jniCall: 调用jni方法.");
    }

    public void jumpSeconActivity(View view) {
//        bitmapException();
//        bitmapBinder();
        bitmapBinder2Process();
    }


    /**
     * 两个进程 传递大图
     */

    private void bitmapBinder2Process() {
        Intent intent = new Intent(this, AnotherProcessActivity.class);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.bit_5mb);
        Log.i("MainActivity", "bitmap大小: " + bitmap.getByteCount() / 1024 + " kb");
        Log.i("MainActivity", "bitmap大小: " + bitmap.getByteCount() / (1024 * 1024) + " mb");
        Bundle bundle = new Bundle();
        IGetBitmapService.Stub bitmapService = new IGetBitmapService.Stub() {
            @Override
            public Bitmap getIntentBitmap() throws RemoteException {
                return bitmap;
            }
        };
        bundle.putBinder("mybinder", bitmapService);
        intent.putExtras(bundle);
        startActivity(intent);
    }

    /**
     * 注意: 这个用法不能跨进程，
     * 大图在同一个进程中传递大于4m的大图.这里bitmap使用到了共享内存.
     */
    private void bitmapBinder() {
        Intent intent = new Intent(this, SecondActivity.class);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.bit_5mb);
        Log.i("MainActivity", "bitmap大小: " + bitmap.getByteCount() / 1024 + " kb");
        Log.i("MainActivity", "bitmap大小: " + bitmap.getByteCount() / (1024 * 1024) + " mb");
        Bundle bundle = new Bundle();
        // 传输的是 aidl 接口
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
//
//        }

        bundle.putBinder("bitmap", new BitmapBinder(bitmap));
//        intent.putExtras(bundle);
        startActivity(intent);

    }

    private void bitmapException() {
        Intent intent = new Intent(this, SecondActivity.class);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_bimap);
        Bundle bundle = new Bundle();
        bundle.putParcelable("image", bitmap);
        intent.putExtras(bundle);
        startActivity(intent);
    }


    public void testPermission(View view) {
        testRequest();
    }
    // 申请权限  函数名可以随意些
    @Permission(value = Manifest.permission.READ_EXTERNAL_STORAGE, requestCode = 200)
    public void testRequest() {
        Toast.makeText(this, "权限申请成功...", Toast.LENGTH_SHORT).show();
    }

    // 权限被取消  函数名可以随意些
    @PermissionCancel
    public void testCancel() {
        Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
    }

    // 多次拒绝，还勾选了“不再提示”
    @PermissionDenied
    public void testDenied() {
        Toast.makeText(this, "权限被拒绝(用户勾选了 不再提示)，注意：你必须要去设置中打开此权限，否则功能无法使用", Toast.LENGTH_SHORT).show();
    }

    /**
     * 埋点测试
     * @param view
     */
    public void testPointEmbedding(View view) {
        Intent intent = new Intent(this, UplodPointActivity.class);
        startActivity(intent);
    }
}
